package com.dbflow5.processor.definition.behavior;

import com.dbflow5.StringUtils;
import com.dbflow5.processor.ProcessorManager;
import com.dbflow5.processor.definition.TableDefinition;
import com.dbflow5.processor.definition.column.ColumnDefinition;
import com.dbflow5.processor.utils.ElementExtensions;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.TypeName;

public class FTSBehaviors {
    public interface FtsBehavior {
        ProcessorManager manager();
        String elementName();

        default void validateColumnDefinition(ColumnDefinition columnDefinition) {
            if (columnDefinition.type != ColumnDefinition.Type.RowId.INSTANCE
                    && !columnDefinition.columnName.equals("rowid")
                    && ElementExtensions.isOneOf(columnDefinition.elementTypeName, Integer.class, Long.class)) {
                manager().logError("FTS4 Table of type $elementName can only have a single primary key named \"rowid\" of type rowid that is an Int or Long type.");
            } else if (columnDefinition.elementTypeName != ClassName.get(String.class)) {
                manager().logError("FTS4 Table of type $elementName must only contain String columns");
            }
        }

        default void addContentTableCode(boolean addComma, CodeBlock.Builder codeBlock) {

        }
    }

    /**
     * Description:
     */
    public static class FTS4Behavior implements FtsBehavior {
        public TypeName contentTable;
        private final TypeName databaseTypeName;

        private final String elementName;
        private final ProcessorManager manager;

        @Override
        public ProcessorManager manager() {
            return manager;
        }

        @Override
        public String elementName() {
            return elementName;
        }

        public FTS4Behavior(TypeName contentTable, TypeName databaseTypeName, String elementName, ProcessorManager manager) {
            this.contentTable = contentTable;
            this.databaseTypeName = databaseTypeName;
            this.elementName = elementName;
            this.manager = manager;
        }

        public void addContentTableCode(boolean addComma, CodeBlock.Builder codeBlock) {
            TableDefinition tableDefinition = manager.getTableDefinition(databaseTypeName, contentTable);
            if(tableDefinition != null) {
                if (addComma) {
                    codeBlock.add(", ");
                }
                codeBlock.add("content="+ StringUtils.quote(tableDefinition.associationalBehavior().name));
            }
        }
    }

    public static class FTS3Behavior implements FtsBehavior{
        private final String elementName;
        private final ProcessorManager manager;

        @Override
        public ProcessorManager manager() {
            return manager;
        }

        @Override
        public String elementName() {
            return elementName;
        }

        public FTS3Behavior(String elementName, ProcessorManager manager) {
            this.elementName = elementName;
            this.manager = manager;
        }
    }
}
